<html>
	<head>
		<title>JSEV Items Test</title>
		<script type="application/javascript" src="../methods.Object.js"></script>
		<script type="application/javascript" src="../methods.Array.js"></script>
		<script type="application/javascript" src="../JSON.schema.reg.js"></script>
		<script type="application/javascript" src="../JSON.path.js"></script>
		<script type="application/javascript" src="../JSON.schema.err.js"></script>
		<script type="application/javascript" src="../JSON.schema.err.messages.en.js"></script>
		<script type="application/javascript" src="../JSON.schema.ext.walker.js"></script>
		<script type="application/javascript" src="../JSON.schema.ext.js"></script>
		<script type="application/javascript">
			function validTest() {
				var schemaA = {"id": "schemaA"},
					schemaB = {"id": "schemaB", "type": "array"},
					schemaC = {"id": "schemaC", "minItems": 3},
					schemaD = {"id": "schemaD", "maxItems": 2},
					schemaE = {"id": "schemaE", "items": [{"type": "integer"}], "additionalItems": false},
					schemaF = {"id": "schemaF", "items": [{"type": "number"}]},
					schemaG = {"id": "schemaG", "items": [{"type": "number"}], "additionalItems": {"type": "integer"}},
					schemaH = {"id": "schemaH", "items": {"type": "number"}},
					schemaI = {"id": "schemaI", "items": [{"type": "number"}, {"type": "string"}]},
					schemaJ = {"id": "schemaJ", "items": [{"type": "number"}, {"type": "string"}], "additionalItems": false},
					schemaK = {"id": "schemaK", "items": [{"type": "number"}, {"type": "string"}], "additionalItems": {"type": "number"}},
					/** Shouldn't produce RequiredTypeErrors RTE000 */
					schema0 = {"items": {"type": "string"}},
					schema1 = {"type": "array", "items": {"type": "string"}},
					schema2 = {"items": [{"type": "string"}, {"type": "boolean"}]},
					schema3 = {"type": "array", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema4 = {"type": "schemaA", "items": {"type": "string"}},
					schema5 = {"extends": "schemaA", "items": {"type": "string"}},
					schema6 = {"type": "schemaA", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema7 = {"extends": "schemaA", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema8 = {"type": "schemaB", "items": {"type": "string"}},
					schema9 = {"extends": "schemaB", "items": {"type": "string"}},
					schema10 = {"type": "schemaB", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema11 = {"extends": "schemaB", "items": [{"type": "string"}, {"type": "boolean"}]},
					/** Shouldn't produce InvalidValueErrors: conflict with minItems IVE002 */
					schema12 = {"type": "schemaC", "items": [{"type": "string"}, {"type": "string"}, {"type": "string"}], "additionalItems": false},
					schema13 = {"extends": "schemaC", "items": [{"type": "string"}, {"type": "string"}, {"type": "string"}], "additionalItems": false},
					schema14 = {"minItems": 3, "items": [{"type": "string"}, {"type": "string"}, {"type": "string"}], "additionalItems": false},
					/** Shouldn't produce InvalidValueErrors: conflict with maxItems IVE003 */
					schema15 = {"type": "schemaD", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema16 = {"extends": "schemaD", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema17 = {"maxItems": 2, "items": [{"type": "string"}, {"type": "boolean"}]},
					/** Shouldn't produce SubTypeErrors: conflict with super items restriction
					    (type must be a subtype of all super items types) STE003 */
					schema18 = {"type": "schemaF", "items": {"type": "integer"}},
					schema19 = {"extends": "schemaF", "items": {"type": "integer"}},
					/** Shouldn't produce SubTypeErrors: conflict with super additionalItems restriction
					    (type must be a subtype of all super items and additionalItems) STE004 */
					schema20 = {"type": "schemaG", "items": {"type": "integer"}},
					schema21 = {"extends": "schemaG", "items": {"type": "integer"}},
					/** Shouldn't produce SubTypeErrors: conflict with super items restriction
					    (all types must be subtypes of the single super items type) STE005 */
					schema22 = {"type": "schemaH", "items": [{"type": "number"}, {"type": "integer"}]},
					schema23 = {"extends": "schemaH", "items": [{"type": "integer"}, {"type": "number"}]},
					/** Shouldn't produce SubTypeErrors: conflict with super items restriction (corresponding types must be subtypes) STE006 */
					schema24 = {"type": "schemaI", "items": [{"type": "integer"}, {"type": "string"}]},
					schema25 = {"extends": "schemaI", "items": [{"type": "integer"}, {"type": "string"}]},
					/** Shouldn't produce SubTypeErrors: conflict with super items and super additionalItems restrictions (too
					    many types in items restriction) IVE005 */
					schema26 = {"type": "schemaJ", "items": [{"type": "integer"}, {"type": "string"}]},
					schema27 = {"extends": "schemaJ", "items": [{"type": "integer"}, {"type": "string"}]},
					/** Shouldn't produce SubTypeErrors: conflict with super additionalItems restriction (no corresponding type in super
					    items so must be a subtype of type specified by additionalItems) STE007 */
					schema28 = {"type": "schemaK", "items": [{"type": "integer"}, {"type": "string"}, {"type": "integer"}]},
					schema29 = {"extends": "schemaK", "items": [{"type": "integer"}, {"type": "string"}, {"type": "integer"}]},
					/** Shouldn't produce SubTypeErrors: conflict with super items restriction (single item must be subtype of single super item) */
					schema30 = {"type": "schemaH", "items": {"type": "integer"}}
					schemasToValidate = [
						schema0, schema1, schema2, schema3, schema4, schema5, schema6, schema7, schema8, schema9, schema10, schema11,
						schema12, schema13, schema14, schema15, schema16, schema17,
						schema18, schema19,
						schema20, schema21,
						schema22, schema23,
						schema24, schema25,
						schema26, schema27, schema28, schema29,
						schema30
					],
					retVal = undefined;

				try {
					JSON.schema.registry.unregister("*");
					JSON.schema.registry.register([schemaA, schemaB, schemaC, schemaD, schemaE, schemaF, schemaG, schemaH, schemaI, schemaJ, schemaK]);
				} catch (e) {
					console.error("Type registration failed: ", e);
				}

				for (var i in schemasToValidate) {
					retVal = JSON.schema.ext.validate(schemasToValidate[i]);
					if (retVal.valid) {
						console.info("Test " + i + " passed!", retVal);
					} else {
						console.warn("Test " + i + " failed.", retVal);
						if (retVal.errors.length > 0) {
							console.group("Error messages:");
							for (var i in retVal.errors) {
								console.info(JSON.schema.err.localize("en", retVal.errors[i]));
							}
							console.groupEnd();
						} else {
							console.info("No errors reported.");
						}
					}
				}
			}

			function invalidTest() {
				var schemaA = {"id": "schemaA", "type": "integer"},
					schemaB = {"id": "schemaB", "disallow": "array"},
					schemaC = {"id": "schemaC", "minItems": 3},
					schemaD = {"id": "schemaD", "maxItems": 2},
					schemaE = {"id": "schemaE", "items": [{"type": "integer"}], "additionalItems": false},
					schemaF = {"id": "schemaF", "items": [{"type": "integer"}]},
					schemaG = {"id": "schemaG", "items": [{"type": "integer"}], "additionalItems": {"type": "string"}},
					schemaH = {"id": "schemaH", "items": {"type": "number"}},
					schemaI = {"id": "schemaI", "items": [{"type": "number"}, {"type": "string"}]},
					schemaJ = {"id": "schemaJ", "items": [{"type": "number"}, {"type": "string"}], "additionalItems": false},
					schemaK = {"id": "schemaK", "items": [{"type": "number"}, {"type": "string"}], "additionalItems": {"type": "integer"}},
					/** RequiredTypeErrors RTE000 */
					schema0 = {"type": "integer", "items": {"type": "string"}},
					schema1 = {"type": ["integer", "array"], "disallow": "array", "items": {"type": "string"}},
					schema2 = {"type": "integer", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema3 = {"type": ["integer", "array"], "disallow": "array", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema4 = {"type": "schemaA", "items": {"type": "string"}},
					schema5 = {"extends": "schemaA", "items": {"type": "string"}},
					schema6 = {"type": "schemaA", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema7 = {"extends": "schemaA", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema8 = {"type": "schemaB", "items": {"type": "string"}},
					schema9 = {"extends": "schemaB", "items": {"type": "string"}},
					schema10 = {"type": "schemaB", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema11 = {"extends": "schemaB", "items": [{"type": "string"}, {"type": "boolean"}]},
					/** InvalidValueErrors: conflict with minItems IVE002 */
					schema12 = {"type": "schemaC", "items": [{"type": "string"}], "additionalItems": false},
					schema13 = {"extends": "schemaC", "items": [{"type": "string"}], "additionalItems": false},
					schema14 = {"minItems": 3, "items": [{"type": "string"}], "additionalItems": false},
					/** InvalidValueErrors: conflict with maxItems IVE003 */
					schema15 = {"type": "schemaD", "items": [{"type": "string"}, {"type": "boolean"}, {"type": "intger"}]},
					schema16 = {"extends": "schemaD", "items": [{"type": "string"}, {"type": "boolean"}, {"type": "intger"}]},
					schema17 = {"maxItems": 2, "items": [{"type": "string"}, {"type": "boolean"}, {"type": "intger"}]},
					/** InvalidValueErrors: conflict with items tuple and additionalItems: false IVE004 */
					schema18 = {"type": "schemaE", "items": {"type": "integer"}},
					schema19 = {"extends": "schemaE", "items": {"type": "integer"}},
					/** SubTypeErrors: conflict with super items restriction
					    (item must be a subtype of all super items) STE003 */
					schema20 = {"type": "schemaF", "items": {"type": "string"}},
					schema21 = {"extends": "schemaF", "items": {"type": "string"}},
					/** SubTypeErrors: conflict with super additionalItems restriction
					    (item must be a subtype of all super items and additionalItems) STE004 */
					schema22 = {"type": "schemaG", "items": {"type": "integer"}},
					schema23 = {"extends": "schemaG", "items": {"type": "integer"}},
					/** SubTypeErrors: conflict with super items restriction
					    (all items must be subtype of single super item) STE005 */
					schema24 = {"type": "schemaH", "items": [{"type": "number"}, {"type": "string"}]},
					schema25 = {"type": "schemaH", "items": [{"type": "string"}, {"type": "number"}]},
					schema26 = {"type": "schemaH", "items": [{"type": "string"}, {"type": "boolean"}]},
					schema27 = {"extends": "schemaH", "items": [{"type": "boolean"}, {"type": "number"}]},
					schema28 = {"extends": "schemaH", "items": [{"type": "number"}, {"type": "boolean"}]},
					schema29 = {"extends": "schemaH", "items": [{"type": "boolean"}, {"type": "string"}]},
					/** SubTypeErrors: conflict with super items restriction (corresponding types must be subtypes) STE006 */
					schema30 = {"type": "schemaI", "items": [{"type": "string"}, {"type": "integer"}]},
					schema31 = {"extends": "schemaI", "items": [{"type": "string"}, {"type": "integer"}]},
					/** SubTypeErrors: conflict with super items and super additionalItems restrictions (too
					    many items in items restriction) IVE005 */
					schema32 = {"type": "schemaJ", "items": [{"type": "integer"}, {"type": "string"}, {"type": "boolean"}]},
					schema33 = {"extends": "schemaJ", "items": [{"type": "integer"}, {"type": "string"}, {"type": "boolean"}]},
					/** SubTypeErrors: conflict with super additionalItems restriction (no corresponding type in super
					    items so must be a subtype of type specified by additionalItems) STE007 */
					schema34 = {"type": "schemaK", "items": [{"type": "integer"}, {"type": "string"}, {"type": "boolean"}]},
					schema35 = {"extends": "schemaK", "items": [{"type": "integer"}, {"type": "string"}, {"type": "boolean"}]},
					/** SubTypeErrors: conflict with super items restriction (single item must be subtype of single super item) */
					schema36 = {"type": "schemaH", "items": {"type": "string"}},
					errorsExpected = [
						["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"], ["RTE000"],
						["IVE002"], ["IVE002"], ["IVE002"],
						["IVE003"], ["IVE003"], ["IVE003"],
						["IVE004"], ["IVE004"],
						["STE003"], ["STE003"],
						["STE004"], ["STE004"],
						["STE005"], ["STE005"], ["STE005", "STE005"], ["STE005"], ["STE005"], ["STE005", "STE005"],
						["STE006", "STE006"], ["STE006", "STE006"],
						["IVE005"], ["IVE005"],
						["STE007"], ["STE007"],
						["STE004"]
					],
					schemasToValidate = [
						schema0, schema1, schema2, schema3, schema4, schema5, schema6, schema7, schema8, schema9, schema10, schema11,
						schema12, schema13, schema14, schema15, schema16, schema17,
						schema18, schema19,
						schema20, schema21,
						schema22, schema23,
						schema24, schema25, schema26, schema27, schema28, schema29,
						schema30, schema31,
						schema32, schema33, schema34, schema35,
						schema36
					],
					retVal = undefined;

				try {
					JSON.schema.registry.unregister("*");
					JSON.schema.registry.register([schemaA, schemaB, schemaC, schemaD, schemaE, schemaF, schemaG, schemaH, schemaI, schemaJ, schemaK]);
				} catch (e) {
					console.error("Type registration failed: ", e);
				}

				function correctErrors(vRetVal, errorsExpected) {
					if (vRetVal.errors.length != errorsExpected.length)
						return false;

					var i = 0;
					for (; i < errorsExpected.length; i++) {
						if (errorsExpected[i] != vRetVal.errors[i].code) {
							return false;
						}
					}
					return true;
				}

				for (var i in schemasToValidate) {
					retVal = JSON.schema.ext.validate(schemasToValidate[i]);
					if (!retVal.valid && correctErrors(retVal, errorsExpected[i])) {
						console.info("Test " + i + " passed!", retVal);
						if (document.getElementById("showInvMsg").checked) {
							console.group("Error Messages for expected errors:");
							for (var j in retVal.errors)
								console.info(JSON.schema.err.localize("en", retVal.errors[j]));
							console.groupEnd();
						}
					} else {
						console.warn("Test " + i + " failed.", retVal);
						console.group("Reason: ");
						var loops = errorsExpected[i].length > retVal.errors.length ?
							errorsExpected[i].length : retVal.errors.length;
						var msg = "";

						for (var j = 0; j < loops; j++) {
							if (
								j in errorsExpected[i] && j in retVal.errors &&
								errorsExpected[i][j] == retVal.errors[j].code
							) continue;

							if (j in errorsExpected[i])
								msg += "Error Expected: " + errorsExpected[i][j];
							else
								msg += "No error expected";

							if (j in retVal.errors)
								msg += ", found: " + retVal.errors[j].code + ".";
							else
								msg += ", no error found."

							console.info(msg);
							msg = "";
						}
						console.groupEnd();
					}
				}
			}
		</script>
	</head>
	<body>
		<div> Tests the `items' restriction check of JSON.schema.ext.validate </div>
		<div><button onclick="validTest();">Valid Schema Test</button></div>
		<div><button onclick="invalidTest();">Invalid Schema Test</button><input type="checkbox" id="showInvMsg"></input><label for="showInvMsg">Show Messages</label></div>
	</body>
</html>